/**
 * API请求封装
 */
import axios from 'axios'
import { getToken } from '@/utils/auth'
import { Toast } from 'vant'
import store from '@/store'

// 默认配置
const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL || '', // 从环境变量获取API基础URL
  timeout: 10000, // 请求超时时间：10秒
  headers: {
    'Content-Type': 'application/json'
  }
})

// 重试配置
const retryConfig = {
  maxRetries: 3,       // 最大重试次数
  retryDelay: 1000,    // 重试间隔时间(ms)
  retryStatusCodes: [408, 429, 500, 502, 503, 504]  // 需要重试的HTTP状态码
}

// 网络状态监控
let isOnline = navigator.onLine
window.addEventListener('online', () => { isOnline = true })
window.addEventListener('offline', () => { 
  isOnline = false
  Toast('网络连接已断开，请检查网络设置')
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 如果离线且不是GET请求，可以选择存储到本地队列
    if (!isOnline && config.method !== 'get') {
      // 可以实现离线请求队列
      console.warn('Network offline, request queued:', config.url)
      return Promise.reject(new Error('网络已断开连接'))
    }
    
    // 显示全局loading
    if (config.showLoading !== false) {
      store.commit('mobile/SET_LOADING', true)
    }
    
    // 获取认证令牌并添加到请求头
    const token = getToken()
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`
    }
    
    // 添加重试标记
    config.__retryCount = 0
    
    return config
  },
  error => {
    // 隐藏loading
    store.commit('mobile/SET_LOADING', false)
    console.error('Request error:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 隐藏loading
    store.commit('mobile/SET_LOADING', false)
    
    const res = response.data
    
    // 根据业务状态码判断请求是否成功
    if (res.code !== 200) {
      // 处理特定错误码
      if (res.code === 401) {
        // Token过期或未登录
        // 可以在此处理登出逻辑
        store.dispatch('user/logout')
        Toast.fail('登录已过期，请重新登录')
      } else {
        // 非静默错误时显示提示
        if (!response.config.silent) {
          Toast.fail(res.message || '请求失败')
        }
      }
      
      // 返回错误信息
      return Promise.reject(new Error(res.message || '请求失败'))
    }
    
    // 返回业务数据
    return res.data
  },
  async error => {
    // 隐藏loading
    store.commit('mobile/SET_LOADING', false)
    
    const config = error.config
    
    // 处理重试逻辑
    if (config && retryConfig.maxRetries > 0) {
      // 判断是否满足重试条件
      const shouldRetry = (
        // 检查是否有重试计数
        config.__retryCount < retryConfig.maxRetries && 
        // 检查错误是否是网络错误或服务器错误
        (
          !error.response || 
          retryConfig.retryStatusCodes.includes(error.response.status) || 
          error.code === 'ECONNABORTED'
        )
      )
      
      if (shouldRetry) {
        config.__retryCount += 1
        console.log(`Retrying request (${config.__retryCount}/${retryConfig.maxRetries}): ${config.url}`)
        
        // 延迟重试
        await new Promise(resolve => setTimeout(resolve, retryConfig.retryDelay))
        
        // 重新发送请求
        return service(config)
      }
    }
    
    // 处理错误提示
    let message = error.message || '请求失败'
    
    // 根据HTTP状态码生成友好提示
    if (error.response) {
      const status = error.response.status
      switch (status) {
        case 400:
          message = '请求参数错误'
          break
        case 401:
          message = '未授权，请重新登录'
          store.dispatch('user/logout')
          break
        case 403:
          message = '拒绝访问'
          break
        case 404:
          message = '请求的资源不存在'
          break
        case 408:
          message = '请求超时'
          break
        case 429:
          message = '请求过于频繁，请稍后再试'
          break
        case 500:
          message = '服务器内部错误'
          break
        case 501:
          message = '服务未实现'
          break
        case 502:
          message = '网关错误'
          break
        case 503:
          message = '服务不可用'
          break
        case 504:
          message = '网关超时'
          break
        default:
          message = `请求失败: ${status}`
      }
    } else if (error.request) {
      // 请求发出但未收到响应
      message = '网络异常，服务器未响应'
    }
    
    // 非静默错误显示提示
    if (config && !config.silent) {
      Toast.fail(message)
    }
    
    return Promise.reject(new Error(message))
  }
)

/**
 * 封装GET请求
 * @param {string} url 请求URL
 * @param {Object} params 请求参数
 * @param {Object} options 其他选项
 * @returns {Promise} 请求Promise
 */
export function get(url, params = {}, options = {}) {
  return service({
    url,
    method: 'get',
    params,
    ...options
  })
}

/**
 * 封装POST请求
 * @param {string} url 请求URL
 * @param {Object} data 请求体数据
 * @param {Object} options 其他选项
 * @returns {Promise} 请求Promise
 */
export function post(url, data = {}, options = {}) {
  return service({
    url,
    method: 'post',
    data,
    ...options
  })
}

/**
 * 封装PUT请求
 * @param {string} url 请求URL
 * @param {Object} data 请求体数据
 * @param {Object} options 其他选项
 * @returns {Promise} 请求Promise
 */
export function put(url, data = {}, options = {}) {
  return service({
    url,
    method: 'put',
    data,
    ...options
  })
}

/**
 * 封装DELETE请求
 * @param {string} url 请求URL
 * @param {Object} params 请求参数
 * @param {Object} options 其他选项
 * @returns {Promise} 请求Promise
 */
export function del(url, params = {}, options = {}) {
  return service({
    url,
    method: 'delete',
    params,
    ...options
  })
}

export default service 